/**
 * 
 */
package idv.takeshi.software.productline.bookstore.application.service.dto;

import idv.takeshi.software.productline.bookstore.domain.model.order.Invoice;
import idv.takeshi.software.productline.bookstore.domain.model.order.Order;
import idv.takeshi.software.productline.bookstore.domain.model.order.Payment;

import java.math.BigDecimal;
import java.util.Date;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;

import org.apache.commons.lang.Validate;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

/**
 * A DTO for maintaining payment operations. 
 * @author takeshi
 *
 */
public class PaymentDto {
	
	@NotNull
	private Long orderId;
	
	@NotNull
	private BigDecimal amount;
	
	private boolean paid;
	
	@Pattern(regexp = "\\D{2,2}+-\\d{7,7}+")
	@NotNull
	private String invoiceNumber;
	
	@Pattern(regexp = ".+")
	@NotNull
	private String previousPath;
	
	/**
	 * Default constructor.
	 */
	public PaymentDto(){}
	
	/**
	 * Initial this DTO by given Order model.
	 * @param payment
	 */
	public PaymentDto(Order order) {
		super();
		Validate.notNull(order, "order shall always not be null");
		Payment payment = null;
		Invoice invoice = null;
		
		payment = order.getPayment();
		invoice = order.getInvoice();
		
		Validate.notNull(payment, "payment shall always not be null");
		Validate.notNull(invoice, "invoice shall always not be null");
		
		this.orderId = order.getId();
		this.amount = payment.getAmount();
		this.paid = payment.isPaid();
		this.invoiceNumber = invoice.getInvoiceNumber();
	}

	/**
	 * @return the orderId
	 */
	public Long getOrderId() {
		return orderId;
	}

	/**
	 * @param orderId the orderId to set
	 */
	public void setOrderId(Long orderId) {
		this.orderId = orderId;
	}

	/**
	 * @return the amount
	 */
	public BigDecimal getAmount() {
		return amount;
	}

	/**
	 * @param amount the amount to set
	 */
	public void setAmount(BigDecimal amount) {
		this.amount = amount;
	}

	/**
	 * @return the paid
	 */
	public boolean isPaid() {
		return paid;
	}

	/**
	 * @param paid the paid to set
	 */
	public void setPaid(boolean paid) {
		this.paid = paid;
	}
	
	/**
	 * @return the invoiceNumber
	 */
	public String getInvoiceNumber() {
		return invoiceNumber;
	}

	/**
	 * @param invoiceNumber the invoiceNumber to set
	 */
	public void setInvoiceNumber(String invoiceNumber) {
		this.invoiceNumber = invoiceNumber;
	}

	/**
	 * @return the previousPath
	 */
	public String getPreviousPath() {
		return previousPath;
	}

	/**
	 * @param previousPath the previousPath to set
	 */
	public void setPreviousPath(String previousPath) {
		this.previousPath = previousPath;
	}

	/**
	 * Load Dto data into payment model.
	 * @param payment
	 */
	public void loadModel(Order order){
		Validate.notNull(order, "order shall always not be null");
		Payment payment = order.getPayment();
		Invoice invoice = order.getInvoice();
		Validate.notNull(payment, "payment shall always not be null");
		Validate.notNull(invoice, "invoice shall always not be null");
		
		Date dateTime = new Date();
		payment.setAmount(amount);
		payment.setPaid(paid);
		payment.setUpdateTime(dateTime);
		
		invoice.setInvoiceNumber(invoiceNumber);
		invoice.setUpdateTime(dateTime);
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
	}
	
}
